package com.team9.fitness.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zrdds.simpleinterface.DDSIF;
import com.zrdds.domain.DomainParticipant;
import com.zrdds.infrastructure.ReturnCode_t;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.Map;
import java.util.HashMap;

/**
 * ZRDDS数据监听器服务
 * 负责订阅ZRDDS主题并处理接收到的数据
 * 使用真正的ZRDDS API，不使用模拟实现
 */
@Service
public class ZRDDSDataListener {

    private static final Logger log = LoggerFactory.getLogger(ZRDDSDataListener.class);

    @Autowired
    private ZRDDSManagerService zrddsManagerService;

    @Autowired
    private ExerciseRecordService exerciseRecordService;

    @Autowired
    private CallbackRegistryService callbackRegistryService;

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    // 定义四个主题
    private static final String[] TOPICS = {
            "User/Action",
            "Exercise/Data",
            "Diet/Record",
            "Community/Activity"
    };

    /**
     * 初始化数据监听器
     */
    @PostConstruct
    public void initialize() {
        try {
            log.info("初始化ZRDDS数据监听器...");

            // 等待ZRDDS管理器初始化完成
            scheduler.scheduleWithFixedDelay(() -> {
                if (zrddsManagerService.isInitialized()) {
                    setupTopicSubscriptions();
                    scheduler.shutdown();
                }
            }, 1, 2, TimeUnit.SECONDS);

        } catch (Exception e) {
            log.error("初始化ZRDDS数据监听器失败", e);
        }
    }

    /**
     * 设置主题订阅
     * 使用ZRDDS的简化接口进行主题订阅
     */
    private void setupTopicSubscriptions() {
        try {
            for (String topicName : TOPICS) {
                setupTopicSubscription(topicName);
            }

            log.info("所有主题订阅设置完成");

        } catch (Exception e) {
            log.error("设置主题订阅失败", e);
        }
    }

    /**
     * 设置单个主题的订阅
     * 使用ZRDDS的简化接口
     */
    private void setupTopicSubscription(String topicName) {
        try {
            // 使用ZRDDS管理器订阅主题
            boolean success = zrddsManagerService.subscribeTopic(topicName);

            if (success) {
                log.info("成功订阅ZRDDS主题: {}", topicName);
            } else {
                log.warn("订阅ZRDDS主题失败: {}", topicName);
            }

        } catch (Exception e) {
            log.error("设置ZRDDS主题订阅异常: topic={}", topicName, e);
        }
    }

    /**
     * 处理接收到的数据
     */
    private void processReceivedData(String topicName, String data) {
        try {
            switch (topicName) {
                case "User/Action":
                    processUserAction(data);
                    break;
                case "Exercise/Data":
                    processExerciseData(data);
                    break;
                case "Diet/Record":
                    processDietRecord(data);
                    break;
                case "Community/Activity":
                    processCommunityActivity(data);
                    break;
                default:
                    log.warn("未知主题: {}", topicName);
            }
        } catch (Exception e) {
            log.error("处理主题数据失败: topic={}, data={}", topicName, data, e);
        }
    }

    private void processUserAction(String data) {
        log.info("处理用户行为数据: {}", data);
        // 这里可以添加具体的业务逻辑
    }

    private void processExerciseData(String data) {
        log.info("处理运动数据: {}", data);
        // 这里可以添加具体的业务逻辑
    }

    private void processDietRecord(String data) {
        log.info("处理饮食记录数据: {}", data);
        // 这里可以添加具体的业务逻辑
    }

    private void processCommunityActivity(String data) {
        log.info("处理社区活动数据: {}", data);
        // 这里可以添加具体的业务逻辑
    }

    /**
     * 销毁资源
     */
    @PreDestroy
    public void destroy() {
        try {
            // 关闭调度器
            if (!scheduler.isShutdown()) {
                scheduler.shutdown();
                try {
                    if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
                        scheduler.shutdownNow();
                    }
                } catch (InterruptedException e) {
                    scheduler.shutdownNow();
                    Thread.currentThread().interrupt();
                }
            }

            log.info("ZRDDS数据监听器资源已清理");

        } catch (Exception e) {
            log.error("清理ZRDDS数据监听器资源失败", e);
        }
    }

    /**
     * 处理用户行为数据
     */
    public void handleUserAction(String data) {
        try {
            log.info("处理用户行为数据: {}", data);
            // 解析JSON数据并处理用户行为
            Map<String, Object> userActionData = objectMapper.readValue(data, Map.class);
            String actionType = (String) userActionData.get("actionType");
            String messageId = (String) userActionData.get("messageId");

            if (messageId != null) {
                // 处理用户行为业务逻辑
                Map<String, Object> result = processUserActionBusinessLogic(actionType, userActionData);

                // 执行回调返回结果
                callbackRegistryService.executeCallback(messageId, result);
            }
        } catch (Exception e) {
            log.error("处理用户行为数据失败: {}", data, e);
        }
    }

    /**
     * 处理运动数据
     */
    public void handleExerciseData(String data) {
        try {
            log.info("处理运动数据: {}", data);
            // 解析JSON数据并处理运动数据
            Map<String, Object> exerciseData = objectMapper.readValue(data, Map.class);
            String actionType = (String) exerciseData.get("actionType");
            String messageId = (String) exerciseData.get("messageId");

            if (messageId != null) {
                // 处理运动业务逻辑
                Map<String, Object> result = processExerciseBusinessLogic(actionType, exerciseData);

                // 执行回调返回结果
                callbackRegistryService.executeCallback(messageId, result);
            }
        } catch (Exception e) {
            log.error("处理运动数据失败: {}", data, e);
        }
    }

    /**
     * 处理饮食记录数据
     */
    public void handleDietRecord(String data) {
        try {
            log.info("处理饮食记录数据: {}", data);
            // 解析JSON数据并处理饮食记录
            Map<String, Object> dietData = objectMapper.readValue(data, Map.class);
            String actionType = (String) dietData.get("actionType");
            String messageId = (String) dietData.get("messageId");

            if (messageId != null) {
                // 处理饮食记录业务逻辑
                Map<String, Object> result = processDietRecordBusinessLogic(actionType, dietData);

                // 执行回调返回结果
                callbackRegistryService.executeCallback(messageId, result);
            }
        } catch (Exception e) {
            log.error("处理饮食记录数据失败: {}", data, e);
        }
    }

    /**
     * 处理社区活动数据
     */
    public void handleCommunityActivity(String data) {
        try {
            log.info("处理社区活动数据: {}", data);
            // 解析JSON数据并处理社区活动
            Map<String, Object> communityData = objectMapper.readValue(data, Map.class);
            String actionType = (String) communityData.get("actionType");
            String messageId = (String) communityData.get("messageId");

            if (messageId != null) {
                // 处理社区活动业务逻辑
                Map<String, Object> result = processCommunityActivityBusinessLogic(actionType, communityData);

                // 执行回调返回结果
                callbackRegistryService.executeCallback(messageId, result);
            }
        } catch (Exception e) {
            log.error("处理社区活动数据失败: {}", data, e);
        }
    }

    /**
     * 处理用户行为业务逻辑
     */
    private Map<String, Object> processUserActionBusinessLogic(String actionType, Map<String, Object> data) {
        Map<String, Object> result = new HashMap<>();

        try {
            switch (actionType) {
                case "LOGIN":
                    result.put("success", true);
                    result.put("message", "用户登录处理成功");
                    result.put("actionType", actionType);
                    break;
                case "REGISTER":
                    result.put("success", true);
                    result.put("message", "用户注册处理成功");
                    result.put("actionType", actionType);
                    break;
                default:
                    result.put("success", true);
                    result.put("message", "用户行为处理成功");
                    result.put("actionType", actionType);
            }
        } catch (Exception e) {
            log.error("处理用户行为业务逻辑失败: actionType={}", actionType, e);
            result.put("success", false);
            result.put("message", "处理用户行为失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 处理运动业务逻辑
     */
    private Map<String, Object> processExerciseBusinessLogic(String actionType, Map<String, Object> data) {
        Map<String, Object> result = new HashMap<>();

        try {
            switch (actionType) {
                case "START_EXERCISE":
                    // 处理开始运动业务逻辑
                    result = processStartExercise(data);
                    break;
                case "END_EXERCISE":
                    // 处理结束运动业务逻辑
                    result = processEndExercise(data);
                    break;
                default:
                    result.put("success", true);
                    result.put("message", "运动数据处理成功");
                    result.put("actionType", actionType);
            }
        } catch (Exception e) {
            log.error("处理运动业务逻辑失败: actionType={}", actionType, e);
            result.put("success", false);
            result.put("message", "处理运动数据失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 处理开始运动业务逻辑
     */
    private Map<String, Object> processStartExercise(Map<String, Object> data) {
        Map<String, Object> result = new HashMap<>();

        try {
            Long userId = Long.valueOf(data.get("userId").toString());
            Long exerciseId = Long.valueOf(data.get("exerciseId").toString());

            log.info("ZRDDS开始处理开始运动业务: userId={}, exerciseId={}", userId, exerciseId);

            // 调用运动记录服务开始运动
            com.team9.fitness.entity.ExerciseRecord exerciseRecord = exerciseRecordService.startExerciseByZRDDS(userId,
                    exerciseId);

            if (exerciseRecord != null) {
                result.put("success", true);
                result.put("message", "运动开始成功");
                result.put("recordId", exerciseRecord.getId());
                result.put("startTime", exerciseRecord.getStartTime());
                result.put("status", exerciseRecord.getStatus());
                log.info("ZRDDS开始运动成功: recordId={}", exerciseRecord.getId());
            } else {
                result.put("success", false);
                result.put("message", "运动开始失败，请检查运动信息或当前运动状态");
                log.warn("ZRDDS开始运动失败: userId={}, exerciseId={}", userId, exerciseId);
            }
        } catch (Exception e) {
            log.error("ZRDDS处理开始运动业务失败", e);
            result.put("success", false);
            result.put("message", "开始运动处理失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 处理结束运动业务逻辑
     */
    private Map<String, Object> processEndExercise(Map<String, Object> data) {
        Map<String, Object> result = new HashMap<>();

        try {
            Long recordId = Long.valueOf(data.get("recordId").toString());
            Double avgHeartRate = data.get("avgHeartRate") != null ? Double.valueOf(data.get("avgHeartRate").toString())
                    : null;
            Double maxHeartRate = data.get("maxHeartRate") != null ? Double.valueOf(data.get("maxHeartRate").toString())
                    : null;
            Double avgSpeed = data.get("avgSpeed") != null ? Double.valueOf(data.get("avgSpeed").toString()) : null;
            Double maxSpeed = data.get("maxSpeed") != null ? Double.valueOf(data.get("maxSpeed").toString()) : null;

            log.info("ZRDDS开始处理结束运动业务: recordId={}", recordId);

            // 调用运动记录服务结束运动
            com.team9.fitness.entity.ExerciseRecord exerciseRecord = exerciseRecordService.endExerciseByZRDDS(
                    recordId, avgHeartRate, maxHeartRate, avgSpeed, maxSpeed);

            if (exerciseRecord != null) {
                result.put("success", true);
                result.put("message", "运动结束成功");
                result.put("recordId", exerciseRecord.getId());
                result.put("endTime", exerciseRecord.getEndTime());
                result.put("duration", exerciseRecord.getDuration());
                result.put("status", exerciseRecord.getStatus());
                log.info("ZRDDS结束运动成功: recordId={}", exerciseRecord.getId());
            } else {
                result.put("success", false);
                result.put("message", "运动结束失败，请检查运动记录状态");
                log.warn("ZRDDS结束运动失败: recordId={}", recordId);
            }
        } catch (Exception e) {
            log.error("ZRDDS处理结束运动业务失败", e);
            result.put("success", false);
            result.put("message", "结束运动处理失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 处理饮食记录业务逻辑
     */
    private Map<String, Object> processDietRecordBusinessLogic(String actionType, Map<String, Object> data) {
        Map<String, Object> result = new HashMap<>();

        try {
            result.put("success", true);
            result.put("message", "饮食记录处理成功");
            result.put("actionType", actionType);
        } catch (Exception e) {
            log.error("处理饮食记录业务逻辑失败: actionType={}", actionType, e);
            result.put("success", false);
            result.put("message", "处理饮食记录失败: " + e.getMessage());
        }

        return result;
    }

    /**
     * 处理社区活动业务逻辑
     */
    private Map<String, Object> processCommunityActivityBusinessLogic(String actionType, Map<String, Object> data) {
        Map<String, Object> result = new HashMap<>();

        try {
            result.put("success", true);
            result.put("message", "社区活动处理成功");
            result.put("actionType", actionType);
        } catch (Exception e) {
            log.error("处理社区活动业务逻辑失败: actionType={}", actionType, e);
            result.put("success", false);
            result.put("message", "处理社区活动失败: " + e.getMessage());
        }

        return result;
    }
}
